!> author: 左志华
!> date: 2022-07-17
module test_easy_string

    use testdrive, only: new_unittest, unittest_type, error_type, check
    use string_disp_m
    use string_m
    use, intrinsic :: iso_c_binding, only: c_null_char
    implicit none
    private

    public :: collect_easy_string

contains

    !> Collect all exported unit tests
    subroutine collect_easy_string(testsuite)
        !> Collection of tests
        type(unittest_type), allocatable, intent(out) :: testsuite(:)

        testsuite = [ &
                    new_unittest("FUNC: test_f_c_string", test_f_c_string), &
                    new_unittest("FUNC: test_to_upper_lower", test_to_upper_lower), &
                    new_unittest("FUNC: test_to_string", test_to_string), &
                    new_unittest("FUNC: test_progress_bar", test_progress_bar), &
                    new_unittest("FUNC: test_starts_with", test_starts_with) &
                    ]

    end subroutine collect_easy_string

    subroutine test_f_c_string(error)
        type(error_type), allocatable, intent(out) :: error
        call check(error, f_c_string("Hello, world!"), "Hello, world!"//c_null_char)
    end subroutine test_f_c_string

    subroutine test_progress_bar(error)
        type(error_type), allocatable, intent(out) :: error
        call check(error, progress_bar("Calc ..", 0.95), &
                   "Calc .. [#################################..]  95.0 %")
    end subroutine test_progress_bar

    subroutine test_starts_with(error)
        type(error_type), allocatable, intent(out) :: error
        call check(error, starts_with("Hello, world!", "Hello"))
        if (allocated(error)) return
        call check(error,.not. starts_with("Hello, world!", "hello"))
        if (allocated(error)) return
        call check(error, starts_with("Hello, world!", "world!", reverse=.true.), "world!")
        if (allocated(error)) return
        call check(error,.not. starts_with("Hello, world!", "Hello", reverse=.true.), "Hello")
        if (allocated(error)) return
        call check(error, starts_with("Hello", "Hello", reverse=.true.), "Hello!")
    end subroutine test_starts_with

    subroutine test_to_string(error)
        type(error_type), allocatable, intent(out) :: error
        call check(error, to_string(1.0, fmt="F3.1"), "1.0")
        if (allocated(error)) return
        call check(error, to_string(1.0_8, fmt="F3.1"), "1.0")
        if (allocated(error)) return
        call check(error, to_string(.true.), "T")
        if (allocated(error)) return
        call check(error, to_string(1, fmt="i0"), "1")
    end subroutine test_to_string

    subroutine test_to_upper_lower(error)
        type(error_type), allocatable, intent(out) :: error
        call check(error, to_lower("Hello, World!", .true.), "HELLO, WORLD!")
        if (allocated(error)) return
        call check(error, to_lower("Hello, World!"), "hello, world!")
    end subroutine test_to_upper_lower

end module test_easy_string
